package net.gz01.wallet.web.controller.admin;

import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileOutputStream;
import java.math.BigDecimal;

import javax.imageio.ImageIO;

import org.apache.commons.lang3.StringUtils;

import com.jfinal.aop.Before;
import com.jfinal.aop.Duang;
import com.jfinal.plugin.activerecord.Page;
import com.jfinal.plugin.activerecord.tx.Tx;

import net.gz01.util.ZODate;
import net.gz01.wallet.common.Certificate;
import net.gz01.wallet.common.PageRespon;
import net.gz01.wallet.common.ZOIDGenerate;
import net.gz01.wallet.common.ZOSearchCondition;
import net.gz01.wallet.message.AccountBalanceChangeResp;
import net.gz01.wallet.web.config.SystemConfig;
import net.gz01.wallet.web.config.SystemEnum.BizType;
import net.gz01.wallet.web.config.SystemEnum.OrderStatus;
import net.gz01.wallet.web.config.SystemEnum.Resp;
import net.gz01.wallet.web.controller.BaseController;
import net.gz01.wallet.web.model.Account;
import net.gz01.wallet.web.model.Channel;
import net.gz01.wallet.web.model.Dictionary;
import net.gz01.wallet.web.model.Merch;
import net.gz01.wallet.web.model.MerchUser;
import net.gz01.wallet.web.model.TradeConfig;
import net.gz01.wallet.web.model.TradeOrder;
import net.gz01.wallet.web.model.YouliAccount;
import net.gz01.wallet.web.noitfy.NotifyThread;
import net.gz01.wallet.web.service.AccountService;
import net.gz01.wallet.web.service.CalcFeeService;
import net.gz01.wallet.web.service.SendSMSConfig;

public class ChargeOrderController extends BaseController {

	private CalcFeeService feeService = new CalcFeeService();
	private AccountService accountService = Duang.duang(AccountService.class);

	public void search() {
		setAttr("params", getRequest().getQueryString());
		setAttr("bizTypeList", Dictionary.dao.selectBizType());
		setAttr("orderStatusList", Dictionary.dao.selectOrderStatus());
		render("trade/chargeOrderList.html");
	}

	public void listJson() {
		ZOSearchCondition sc = super.getSearchCondition();
		sc.setParameter("bizType", BizType.Charge.getValue());
		sc.setParameter("bizType2", BizType.Transfer_xx.getValue());
		Page<TradeOrder> pageResult = TradeOrder.dao.search(sc);
		renderJson(new PageRespon(pageResult));
	}

	public void addPage() {
		render("trade/chargeOrderAdd.html");
	}

	public void add() {
		TradeOrder tradeOrder = getModel(TradeOrder.class);
		TradeConfig config = TradeConfig.dao.selectCharge(tradeOrder.getMerchCode());
		if (config == null) {
			renderFail("充值提交失败,未找到商户充值配置");
			return;
		}

		Account ac = Account.dao.select(tradeOrder.getMerchCode());
		if (ac == null) {
			renderFail("充值提交失败,未找到商户对应的虚账账户");
			return;
		}
		YouliAccount youliAccount = YouliAccount.dao.findById(tradeOrder.getYouliAccountId());
		if (youliAccount == null) {
			renderFail("充值提交失败,未找到商户对应的收款卡信息");
			return;
		}

		BigDecimal amount = new BigDecimal(getPara("amount")).multiply(new BigDecimal(100));
		if (amount.longValue() > 99999999900L) {
			renderFail("充值提交失败,金额超过9亿,请分多笔支付!");
			return;
		}
		// 检查充值的交易配置
		TradeConfig tradeConfig = TradeConfig.dao.selectCharge(tradeOrder.getMerchCode());
		if (tradeConfig == null) {
			renderFail("找不到充值交易配置，请联系管理员");
			return;
		}
		Integer fee = feeService.getFee(amount.intValue(), tradeConfig.getFeeId());
		if (fee < 0) {
			renderFail("费率模式不存在");
			return;
		}
		if (amount.longValue() < fee.longValue()) {
			renderFail("充值(收款)金额不足以支付手续费");
			return;
		}
		// 保存收款(充值)订单
		tradeOrder.setId(ZOIDGenerate.getUUID());
		tradeOrder.setChannelCode(config.getChannelCode());
		tradeOrder.setOrderNo(ZOIDGenerate.getSixOrderNo());
		tradeOrder.setOutOrderNo(tradeOrder.getOrderNo());
		tradeOrder.setFee(fee.longValue());
		tradeOrder.setAmount(amount.longValue());
		tradeOrder.setOrderStatus(OrderStatus.FirstReview.getValue());
		tradeOrder.setCreateTime(ZODate.getDateTime());
		tradeOrder.setBizType(BizType.Charge.getValue());
		tradeOrder.save();
		renderSuccess();
	}

	public void firstReviewPage() {
		TradeOrder item = TradeOrder.dao.findById(getPara("id"));
		setAttr("item", item);
		setAttr("channel", Channel.dao.selectByCode(item.getChannelCode()));
		setAttr("merch", Merch.dao.selectByMerchCode(item.getMerchCode()));
		render("trade/chargeOrderFirstReview.html");
	}

	public void secondReviewPage() {
		TradeOrder item = TradeOrder.dao.findById(getPara("id"));
		setAttr("item", item);
		setAttr("channel", Channel.dao.selectByCode(item.getChannelCode()));
		setAttr("merch", Merch.dao.selectByMerchCode(item.getMerchCode()));
		render("trade/chargeOrderSecondReview.html");
	}

	/**
	 * 充值(收款)一审
	 */
	@Before(Tx.class)
	public void firstReview() {
		TradeOrder item = TradeOrder.dao.findById(getPara("id"));
		String reviewResult = getPara("reviewResult");
		String purpose = getPara("purpose");

		if (OrderStatus.FirstReview.getValue().equals(item.getOrderStatus()) && "unPass".equals(reviewResult)) {
			String remark = getPara("remark");
			if (StringUtils.isBlank(remark)) {
				renderMsg(2, "审核不通过的备注信息必须填写!");
				return;
			}
			item.setPurpose(remark);
			item.setRespCode(Resp.Fail.getCode());
			item.setRespMsg(remark);
			item.setOrderStatus(OrderStatus.FirstReviewFail.getValue());
			item.update();
			renderSuccess("此订单已经审核不通过，请走退款流程!");
			return;
		}

		if (OrderStatus.FirstReview.getValue().equals(item.getOrderStatus()) && "pass".equals(reviewResult)) {
			if (StringUtils.isBlank(purpose)) {
				renderMsg(2, "审核通过的信息必须填写!");
				return;
			}
			item.setPurpose(purpose);
			item.setRespCode(Resp.Success.getCode());
			item.setRespMsg("一审成功");
			item.setOrderStatus(OrderStatus.SecondReview.getValue());
			item.update();
			renderSuccess("一审成功");
		}
	}

	/**
	 * 充值(收款)二审
	 */
	@Before(Tx.class)
	public void secondReview() {
		TradeOrder item = TradeOrder.dao.findById(getPara("id"));
		String reviewResult = getPara("reviewResult");
		String purpose2 = getPara("purpose2");

		// 二审不通过
		if (OrderStatus.SecondReview.getValue().equals(item.getOrderStatus()) && reviewResult.equals("unPass")) {
			String remark = getPara("remark");
			if (StringUtils.isBlank(remark)) {
				renderMsg(2, "审核不通过的备注信息必须填写!");
				return;
			}
			item.setPurpose2(remark);
			item.setRespCode(Resp.Fail.getCode());
			item.setRespMsg(remark);
			item.setOrderStatus(OrderStatus.SecondReviewFail.getValue());
			item.update();
			renderSuccess("此订单已经审核不通过，请走退款流程!");
			return;
		}

		// 二审通过
		if (OrderStatus.SecondReview.getValue().equals(item.getOrderStatus()) && "pass".equals(reviewResult)) {
			if (StringUtils.isBlank(purpose2)) {
				renderMsg(2, "审核通过的信息必须填写!");
				return;
			}
			Long chargeAmount = Math.abs(item.getAmount()) - item.getFee();
			if (chargeAmount < 0L) {
				item.setRespCode(Resp.Fail.getCode());
				item.setRespMsg("一充值失败:充值金额不够扣手续费");
				item.setOrderStatus(OrderStatus.Fail.getValue());
				item.update();
				renderFail("充值失败:充值金额不够扣手续费");
				return;
			}
			AccountBalanceChangeResp resp = accountService.addMoney(item.getMerchCode(), chargeAmount);

			if (resp.getRespCode().equals("SUCCESS")) {
				String resMsg = "充值成功";
				if(item.getBizType().equals(BizType.Transfer_xx.getValue())){
					resMsg = "商城消费打款成功";
					NotifyThread.getInstance().addNotifyOrder(item);//异步通知 老铁牛商城这笔线下转账支付成功，可以发货给消费者了。
				}
				item.setPurpose2(purpose2);
				item.setBalance(Long.parseLong(resp.getBalance()));
				item.setOrderStatus(OrderStatus.Success.getValue());
				item.setRespCode(Resp.Success.getCode());
				item.setRespMsg(Resp.Success.getMsg());
				item.setPayTime(ZODate.getDateTime());
				//充值成功统一存友利账户
				item.setOutAccountName(item.getAccountName());
				item.setOutAccountNo(item.getAccountNo());
				item.setOutBankName(item.getBankName());

				MerchUser user = MerchUser.dao.selectByMerCode(item.getMerchCode());
				String smsMsg = "通知短信发送失败";
				if(user != null) {
					//发送短信 充值成功
					boolean isOK = SendSMSConfig.sendSMSAddMenoy(user.getUserName(), Math.abs(item.getAmount()) + "", resp.getBalance());
					if (isOK) {
						smsMsg = "通知短信发送成功";
					}
				}
				if(StringUtils.isNotEmpty(item.getNotifyUrl())) {
					//开始异步回调线程
					NotifyThread.getInstance().addNotifyOrder(item);
				}
				renderSuccess(resMsg + "," + smsMsg);
			} else {
				item.setOrderStatus(OrderStatus.Fail.getValue());
				item.setRespCode(Resp.Fail.getCode());
				item.setRespMsg(Resp.Fail.getMsg());
				renderFail("充值失败:" + resp.getRespMsg());
			}
			item.update();
		}
	}

	/** 展示电子回单图形 */
	public void certificate() throws Exception {
		File file = new File(SystemConfig.config.get("file_center_path") + "certificate/" + getPara("id") + ".jpg");
		if (file.exists()) {
			renderFile(file);
		} else {
			TradeOrder order = TradeOrder.dao.findById(getPara("id"));
			BufferedImage image = Certificate.createImage(order);
			FileOutputStream fos = new FileOutputStream(file);
			ImageIO.write(image, "jpeg", fos);
			fos.close();
			renderFile(file);
		}
	}

}
